package util

type MyList struct {
	Head  *ListNode
	Tail  *ListNode
	Len   int
	Cur   *ListNode
	Index int
}

type ListNode struct {
	Data any
	Next *ListNode
	Prev *ListNode
}

func (this *MyList) AddTail(data any) *ListNode {
	node := &ListNode{Data: data}
	if this.Len == 0 {
		this.Head = node
		this.Tail = node
		this.Cur = node
	} else {
		this.Tail.Next = node
		node.Prev = this.Tail
		this.Tail = node
	}
	this.Len++
	return node
}

func (this *MyList) AddHead(data any) *ListNode {
	node := &ListNode{Data: data}
	if this.Len == 0 {
		this.Head = node
		this.Tail = node
		this.Cur = node
	} else {
		this.Head.Prev = node
		node.Next = this.Head
		this.Head = node
	}
	this.Len++
	return node
}

func (this *MyList) RemoveTail() *ListNode {
	if this.Len == 0 {
		return nil
	}
	if this.Len == 1 {
		this.Head = nil
		this.Tail = nil
		this.Cur = nil
		this.Index = 0
		this.Len = 0
		return this.Tail
	}
	tail := this.Tail
	tail.Prev.Next = nil
	this.Tail = tail.Prev
	this.Len--
	if this.Index == this.Len {
		this.Index = this.Len - 1
		this.Cur = this.Tail
	}
	return tail
}

func (this *MyList) RemoveHead() *ListNode {
	if this.Len == 0 {
		return nil
	}
	if this.Len == 1 {
		this.Head = nil
		this.Tail = nil
		this.Cur = nil
		this.Index = 0
		this.Len = 0
		return this.Head
	}
	head := this.Head
	head.Next.Prev = nil
	this.Head = head.Next
	this.Len--
	if this.Index == 0 {
		this.Cur = this.Head
	}
	return head
}

func (this *MyList) RemoveByIndex() *ListNode {
	if this.Len == 0 {
		return this.RemoveHead()
	}
	if this.Index == this.Len-1 {
		return this.RemoveTail()
	}
	this.Len--
	node := this.Cur
	node.Prev.Next = node.Next
	node.Next.Prev = node.Prev
	return node
}
